#include "easyc_ds.h"
#include <stdlib.h>
#include<stddef.h>
/*
* pop an element from stack
*/
int easyc_pop(c_stack *s){
    if(s->point<=0) {
        printf("EmptyStackException\n");
        return 0;
    }
    int temp=s->point;
    s->point--;
    return *(s->base+temp);       
}

/* 
*  push an element to stack 
*  If fail return 0;else return a positive integer.
*/
int easyc_push(int e, c_stack *s){
    if(s->point==s->size){
        realloc(s->base,sizeof(int)*(s->size+s->base_size));
    }
    s->point++;
    *(s->base+s->point)=e;
    return 1;
}

/*get top element*/
int easyc_get_top(c_stack *s){
    return *(s->base+s->point);
}

/* creat stack with default size */
c_stack make_stack(int size){
    c_stack s;
    s.size=size;
    s.base_size=10;
    s.point=0;
    s.base=(int *)malloc(sizeof(int)*size);
    s.pop=easyc_pop;
    s.push=easyc_push;
    s.get_top=easyc_get_top;
    return s;
}

/* remove the stack, and release the memory space */
void easyc_del(c_stack *s){
    while(s->size>=0){
        int *t=s->base+s->size;
        free(t);
        s->size--;
    }
    free(s);
}

/* list functions */
/* list functions */
/* list functions */
/* list functions */
c_linkedlist linkedlist_make(){
    c_linkedlist s;
    s.size=0;
    s.head=NULL;/* it's necessary */
    s.contains=easyc_list_contains;
    s.insert=easyc_list_insert;
    s.append=easyc_list_append;
    s.remove=easyc_list_remove;
    return s;
}
c_list *easyc_list_find(int e, const struct easyc_linkedlist * t){
   c_list *l;
   int flag=0;/* if not found flag=0 */
   l=t->head;
   if(l==NULL) return NULL;   
   while(l!=NULL){
        if(e==l->element) {
            flag=1; break; /* element found */
        }
        l=l->next;
    }
    return l;
}
/* if found returns -1 else returns 1 */
int easyc_list_contains(int e, const struct easyc_linkedlist * t){
    c_list *l;
    l=t->head;
    while(l!=NULL){
        if(e==l->element) {
           break; /* element found */
        }
        
        l=l->next;
    }
    if(l==NULL) return -1;
    return 1;
}

void easyc_list_insert(int e,const c_list * li,struct easyc_linkedlist * t){
    c_list * l;
    c_list * ins;
    c_list * temp;
    l=t->head;
    while(l!=NULL){
        if(l==li){
            ins=(c_list *)malloc(sizeof(c_list));
            ins->element=e;
            ins->pre=NULL;
            ins->next=NULL;
            if(l->next==NULL) {
                l->next=ins;
                ins->next=NULL;
                ins->pre=l;
                break;
            }else{
                temp=l->next;
                l->next=ins;
                ins->next=temp;
                ins->pre=l;
                temp->pre=ins;
                break;
            }                        
        }
    }
    return;
}

void easyc_list_append(int e,struct easyc_linkedlist * t){
    c_list * l;
    c_list * ins;
    c_list * temp;    
    ins=(c_list *)malloc(sizeof(c_list));
    ins->element=e;
    ins->pre=NULL;
    ins->next=NULL;
    l=t->head;
    if(l==NULL){
        t->head=ins;
        ins->next=NULL;
    }else{
        temp=t->head;
        t->head=ins;
        ins->next=temp;
        temp->pre=ins;        
    }
    return;   
}
void easyc_list_remove(c_list * r,c_linkedlist * t){
    c_list * temp=r;
    if(temp->next==NULL){
        if(r->pre==NULL) {
            t->head=NULL;
            free(temp);
        }else{
            r->pre->next=NULL; 
            free(temp);           
        }
    }
    else{
        if(r->pre==NULL){
            t->head=r->next;
            t->head->pre=NULL;
            free(r);            
        }else{
            r->pre->next=r->next;
            r->next->pre=r->pre;
            free(r);
        }
    }
}
